package cn.com.mdx.collection.queue;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * 先进先出 - FIFO
 *
 * @author huangyuan
 * @date 2020/7/8
 * @description 队列 - 链表实现
 */
public class LinkedQueue<Item> implements Iterable<Item> {
    /**
     * 队列容量
     */
    private int size;

    /**
     * 队列头指针
     */
    private Node<Item> first;

    /**
     * 队列尾指针
     */
    private Node<Item> last;

    /**
     * 节点类
     */
    private static class Node<Item> {
        private final Item item;
        private Node<Item> next;

        public Node(Item item, Node<Item> next) {
            this.item = item;
            this.next = next;
        }
    }

    /**
     * @param item 入队列数据
     * @return void
     * @Author huangy
     * @description //TODO 入队列
     * @date 5:16 下午 2020/8/12
     **/
    public void enqueue(Item item) {
        Node<Item> oldLast = last;
        last = new Node<>(item, null);
        if(isEmpty()) first = last;
        else oldLast.next = last;
        size++;
    }

    /**
     * @return Item 返回的数据
     * @Author huangy
     * @description //TODO 出队列
     * @date 5:17 下午 2020/8/12
     **/
    public Item dequeue() {
        if(isEmpty()) throw new UnsupportedOperationException("队列为空");
        Item item = first.item;
        first = first.next;
        size--;
        return item;
    }

    /**
     * @return int 队列容量
     * @Author huangy
     * @description //TODO 队列容量
     * @date 5:18 下午 2020/8/12
     **/
    public int size() {
        return size;
    }

    /**
     * @return boolean true 表示空 false 表示不为空
     * @Author huangy
     * @description //TODO 查看队列是否为空
     * @date 5:18 下午 2020/8/12
     **/
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * @return java.util.Iterator
     * @Author huangy
     * @description //TODO 获取队列迭代器
     * @date 5:20 下午 2020/8/12
     **/
    @Override
    public Iterator<Item> iterator() {
        return new LinkedQueueIterator();
    }

    /**
     * 迭代器
     */
    private class LinkedQueueIterator implements Iterator<Item> {
        Node<Item> tail = first;
        @Override
        public boolean hasNext() {
            return tail != null;
        }

        @Override
        public Item next() {
            if(!hasNext()) throw new NoSuchElementException("元素不存在无法遍历");
            Item item = tail.item;
            tail = tail.next;
            return item;
        }
    }

    public static void main(String[] args) {
        LinkedQueue<Integer> linkedQueue = new LinkedQueue<>();
        linkedQueue.enqueue(1);
        linkedQueue.enqueue(2);
        linkedQueue.enqueue(3);
        System.out.println(linkedQueue.dequeue());
        System.out.println("-----------------------------------");
        linkedQueue.enqueue(100);
        linkedQueue.enqueue(101);
        linkedQueue.enqueue(102);
        for (int i: linkedQueue) System.out.println(i);
        System.out.println("-----------------------------------");
        System.out.println(linkedQueue.dequeue());
        System.out.println(linkedQueue.dequeue());
        System.out.println(linkedQueue.dequeue());
        System.out.println("-----------------------------------");
        for (int i: linkedQueue) System.out.println(i);
    }


}
